home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------------------
- //
- // File: BlendProcs.c
- //
- // Contents: Procedures that render blended fills.
- //
- //
- // By Georgiann ("George") Delaney
- // © 1989 - 1990, Apple Computer, Inc.
- //
- //--------------------------------------------------------------------------------------*/
-
-
-
-
- #pragma segment BlendSeg
-
-
- #include "MacHeaders.h"
-
-
-
- /*--------------------------------------------------------------------------------------*/
- /* Constants */
-
- #define kGrayPatternRsrc 50
- #define kNumGrayPatterns 50
-
-
-
- /*--------------------------------------------------------------------------------------*/
- /* Macro definitions */
-
- #define RECT_BLEND_BAND_COUNT(span,bandWidth) (((span-bandWidth)/2)/bandWidth)
- #define RECT_BLEND_BAND_INC(span,bandCount,bandWidth) (((span-bandWidth)/2)/bandCount)
- #define RECT_BLEND_STEP(span,bandWidth) (65535/(((span/2)-(bandWidth/2))/bandWidth))
-
- #define LINEAR_BLEND_BAND_COUNT(span,bandWidth) (span/bandWidth)
- #define LINEAR_BLEND_STEP(span,bandWidth) (65535/(span/bandWidth))
-
-
- #define MIN(x,y) (((x) < (y)) ? (x) : (y))
- #define MAX(x,y) (((x) > (y)) ? (x) : (y))
-
-
-
- /*--------------------------------------------------------------------------------------*/
- void HLSRectBlend(Rect *boundRect, short saturation)
- /*
- // This procedure fills the specified rect with a concentric rectangular HLS blend
- // at the specified saturation. The band size used for this fill is 1 pixel. It is
- // assumed that the desired port as well as any desired clipping has already been set.
- */
- {
- RGBColor holdRGB,theRGB;
- HSVColor theHSV;
- short blendStep;
- short i;
- short span;
- Rect tempRect;
-
-
- tempRect = *boundRect;
-
- /* calculate the diameter of the specified rect */
- span = MIN((tempRect.right-tempRect.left)/2, (tempRect.bottom - tempRect.top)/2);
-
- /* calculate the color increment for each band */
- blendStep = 65536 / span;
-
- /* save off the current RGB */
- GetForeColor(&holdRGB);
-
- /* set the initial color */
- theHSV.value = 65535;
- theHSV.saturation = saturation;
- theHSV.hue = 0;
-
- /* Generate the blend by converting the hls (hsv in mac terms) to
- its RGB equivalent. Set the forecolor to this RGB value. Paint
- the rect. Then increment the HLS value and band rect for the next
- iteration
- */
- for (i=0; i<span; i++) {
- HSV2RGB(&theHSV,&theRGB);
- RGBForeColor(&theRGB);
- PaintRect(&tempRect);
- theHSV.hue += blendStep;
- tempRect.top +=1;
- tempRect.left +=1;
- tempRect.right -=1;
- tempRect.bottom -=1;
- }
-
- /* restore the original RGB */
- RGBForeColor(&holdRGB);
- }
-
-
- /*--------------------------------------------------------------------------------------*/
- void HLSVLinearBlend(Rect *boundRect, short saturation)
- /*
- // This procedure fills the specified rect with a vertical HLS blend
- // at the specified saturation. The band size used for this fill is 1 pixel. It is
- // assumed that the desired port as well as any desired clipping has already been set.
- */
- {
- RGBColor holdRGB,theRGB;
- HSVColor theHSV;
- short blendStep;
- short height;
- Rect tempRect;
- short i;
-
-
- tempRect = *boundRect;
-
- /* calculate the vertical distance the blend is to cover */
- height = tempRect.bottom - tempRect.top;
-
- /* calculate the color increment for each band */
- blendStep = 65535 / height;
-
- /* save off the current RGB */
- GetForeColor(&holdRGB);
-
- /* set the initial color */
- theHSV.value = 65535;
- theHSV.saturation = saturation;
- theHSV.hue = 0;
-
- /* Initialize the rectangle that specifies the first band of the blend */
- tempRect.bottom = tempRect.top + 1;
-
- /* Generate the blend by converting the hls (hsv in mac terms) to
- its RGB equivalent. Set the forecolor to this RGB value. Paint
- the rect. Then increment the HLS value and offset the band rect for
- the next iteration
- */
- for (i=0; i<height; i++) {
- HSV2RGB(&theHSV,&theRGB);
- RGBForeColor(&theRGB);
- PaintRect(&tempRect);
- theHSV.hue += blendStep;
- tempRect.top +=1;
- tempRect.bottom +=1;
- }
-
- /* restore the original RGB */
- RGBForeColor(&holdRGB);
- }
-
-
- /*--------------------------------------------------------------------------------------*/
- void HLSHLinearBlend(Rect *boundRect, short saturation)
- /*
- // This procedure fills the specified rect with a horizontal HLS blend
- // at the specified saturation. The band size used for this fill is 1 pixel. It is
- // assumed that the desired port as well as any desired clipping has already been set.
- */
- {
- RGBColor holdRGB,theRGB;
- HSVColor theHSV;
- short blendStep;
- short width;
- Rect tempRect;
- short i;
-
-
- tempRect = *boundRect;
-
- /* calculate the horizontal distance the blend is to cover */
- width = tempRect.right-tempRect.left;
-
- /* calculate the color increment for each band */
- blendStep = 65535 / width;
-
- /* save off the current RGB */
- GetForeColor(&holdRGB);
-
- /* set the initial color */
- theHSV.value = 65535;
- theHSV.saturation = saturation;
- theHSV.hue = 0;
-
- /* Initialize the rectangle that specifies the first band of the blend */
- tempRect.right = tempRect.left + 1;
-
- /* Generate the blend by converting the hls (hsv in mac terms) to
- its RGB equivalent. Set the forecolor to this RGB value. Paint
- the rect. Then increment the HLS value and offset the band rect for
- the next iteration
- */
- for (i=0; i<width; i++) {
- HSV2RGB(&theHSV,&theRGB);
- RGBForeColor(&theRGB);
- PaintRect(&tempRect);
- theHSV.hue += blendStep;
- tempRect.left +=1;
- tempRect.right +=1;
- }
-
- /* restore the original RGB */
- RGBForeColor(&holdRGB);
- }
-
-
- /*--------------------------------------------------------------------------------------*/
- void GrayRectBlend(Rect *boundRect)
- /*
- // This procedure fills the specified rect with a concentric rectangular gray scale blend
- // from black to white. The band size used for this fill is 1 pixel. It is
- // assumed that the desired port as well as any desired clipping has already been set.
- */
- {
- RGBColor holdRGB,theRGB;
- short blendStep;
- short i;
- short span;
- Rect tempRect;
-
-
- tempRect = *boundRect;
-
- /* calculate the diameter of the specified rect */
- span = MIN((tempRect.right-tempRect.left)/2, (tempRect.bottom - tempRect.top)/2);
-
- /* calculate the color increment for each band */
- blendStep = 65536 / span;
-
- /* save off the current RGB color */
- GetForeColor(&holdRGB);
-
- /* set the initial color */
- theRGB.red = theRGB.green = theRGB.blue = 0;
-
- /* Generate the blend by seting the forecolor to the RGB value. Paint
- the rect. Then increment the RGB value and band rect for the next
- iteration
- */
- for (i=0; i<span; i++) {
- RGBForeColor(&theRGB);
- PaintRect(&tempRect);
- theRGB.red = theRGB.green = theRGB.blue = theRGB.red + blendStep;
- tempRect.top +=1;
- tempRect.left +=1;
- tempRect.right -=1;
- tempRect.bottom -=1;
- }
-
- /* restore the original RGB */
- RGBForeColor(&holdRGB);
- }
-
-
- /*--------------------------------------------------------------------------------------*/
- void GrayVLinearBlend(Rect *boundRect)
- /*
- // This procedure fills the specified rect with a vertical gray scale blend
- // from black to white. The band size used for this fill is 1 pixel. It is
- // assumed that the desired port as well as any desired clipping has already been set.
- */
- {
- RGBColor holdRGB,theRGB;
- short blendStep;
- short i;
- short height;
- Rect tempRect;
-
-
- tempRect = *boundRect;
-
- /* calculate the vertical distance the blend is to cover */
- height = tempRect.bottom - tempRect.top;
-
- /* calculate the color increment for each band */
- blendStep = 65535 / height;
-
- /* save off the current RGB color */
- GetForeColor(&holdRGB);
-
- /* set the initial color */
- theRGB.red = theRGB.green = theRGB.blue = 0;
-
- /* Initialize the rectangle that specifies the first band of the blend */
- tempRect.bottom = tempRect.top + 1;
-
- /* Generate the blend by setting the forecolor to this RGB value. Paint
- the rect. Then increment the RGB value and offset the band rect for
- the next iteration
- */
- for (i=0; i<height; i++) {
- RGBForeColor(&theRGB);
- PaintRect(&tempRect);
- theRGB.red = theRGB.green = theRGB.blue = theRGB.red + blendStep;
- tempRect.top +=1;
- tempRect.bottom +=1;
- }
-
- /* restore the original RGB */
- RGBForeColor(&holdRGB);
- }
-
-
- /*--------------------------------------------------------------------------------------*/
- void GrayHLinearBlend(Rect *boundRect)
- /*
- // This procedure fills the specified rect with a horizontal gray scale blend
- // from black to white. The band size used for this fill is 1 pixel. It is
- // assumed that the desired port as well as any desired clipping has already been set.
- */
- {
- RGBColor holdRGB,theRGB;
- short blendStep;
- short i;
- short width;
- Rect tempRect;
-
-
- tempRect = *boundRect;
-
- /* calculate the horizontal distance the blend is to cover */
- width = tempRect.right-tempRect.left;
-
- /* calculate the color increment for each band */
- blendStep = 65535 / width;
-
- /* save off the current RGB color */
- GetForeColor(&holdRGB);
-
- /* set the initial color */
- theRGB.red = theRGB.green = theRGB.blue = 0;
-
- /* Initialize the rectangle that specifies the first band of the blend */
- tempRect.right = tempRect.left + 1;
-
- /* Generate the blend by setting the forecolor to this RGB value. Paint
- the rect. Then increment the RGB value and offset the band rect for
- the next iteration
- */
- for (i=0; i<width; i++) {
- RGBForeColor(&theRGB);
- PaintRect(&tempRect);
- theRGB.red = theRGB.green = theRGB.blue = theRGB.red + blendStep;
- tempRect.left +=1;
- tempRect.right +=1;
- }
-
- /* restore the original RGB */
- RGBForeColor(&holdRGB);
- }
-
- /*--------------------------------------------------------------------------------------*/
- void GrayPatRectBlend(Rect *boundRect)
- /*
- // This procedure fills the specified rect with a concentric rectangular gray scale pattern blend
- // from black to white. The band size used for this fill is calculated by dividing the shorter
- // the horizontal and vertical diameters of the specified rect by the number of gray patterns in
- // the gray pattern resource. It is assumed that the desired port as well as any desired clipping
- // has already been set.
- */
-
- {
- register i;
- double bandWidth;
- double distance;
- Rect origRect,tempRect;
- Pattern thePat;
-
-
- origRect = tempRect = *boundRect;
-
- /* calculate the width of each band */
- bandWidth = (double)(MIN((tempRect.right-tempRect.left)/2, (tempRect.bottom-tempRect.top)/2)) / (double)(kNumGrayPatterns+1);
- distance = bandWidth;
-
- /* There is a pattern resource consisting of 64 shades of gray in MacLib.rsrc
- // that gives a pretty good approximation of a gray ramp from white to black.
- // The following loop performs the actual imaging of the ramp's 64 gray bands.
- */
- for (i=kNumGrayPatterns; i>=1; i--) {
- GetIndPattern(&thePat, kGrayPatternRsrc, i);
- FillRect(&tempRect,thePat);
-
- distance += bandWidth;
- tempRect.top = origRect.top + distance;
- tempRect.left = origRect.left + distance;
- tempRect.right = origRect.right - distance;
- tempRect.bottom = origRect.bottom - distance;
- }
- }
-
-
- /*--------------------------------------------------------------------------------------*/
- void GrayPatVLinearBlend(Rect *boundRect)
- /*
- // This procedure fills the specified rect with a vertical gray scale pattern blend
- // from black to white. The band size used for this fill is calculated by dividing the width
- // of the specified blend by the number of gray patterns in the gray pattern resource. It is
- // assumed that the desired port as well as any desired clipping has already been set.
- */
- {
- register i;
- double theTop;
- double bandHeight;
- double distance;
- Rect tempRect;
- Pattern thePat;
-
-
- tempRect = *boundRect;
-
- /* silly, but saves a pointer dereference in the blend loop */
- theTop = (double)tempRect.top;
-
- /* calculate the width of each band */
- bandHeight = ((double)(tempRect.bottom-tempRect.top)) / (double)kNumGrayPatterns;
-
- /* Initialize the rectangle that specifies the first band of the blend */
- tempRect.bottom = tempRect.top + bandHeight;
- distance = bandHeight;
-
- /* There is a pattern resource consisting of 64 shades of gray in MacLib.rsrc
- // that gives a pretty good approximation of a gray ramp from white to black.
- // The following loop performs the actual imaging of the ramp's 64 gray bands.
- */
- for (i=kNumGrayPatterns; i>1; i--) {
- GetIndPattern(&thePat, kGrayPatternRsrc, i);
- FillRect(&tempRect,thePat);
-
- distance += bandHeight;
- tempRect.top = tempRect.bottom;
- tempRect.bottom = (short)(theTop + distance);
- }
-
- tempRect.bottom = boundRect->bottom;
- GetIndPattern(&thePat,kGrayPatternRsrc,1);
- FillRect(&tempRect,thePat);
- }
-
-
- /*--------------------------------------------------------------------------------------*/
- void GrayPatHLinearBlend(Rect *boundRect)
- /*
- // This procedure fills the specified rect with a horizontal gray scale pattern blend
- // from black to white. The band size used for this fill is calculated by dividing the width
- // of the specified blend by the number of gray patterns in the gray pattern resource. It is
- // assumed that the desired port as well as any desired clipping has already been set.
- */
- {
- register i;
- double farLeft;
- double bandWidth;
- double distance;
- Rect tempRect;
- Pattern thePat;
-
-
- tempRect = *boundRect;
-
- /* silly, but saves a pointer dereference in the blend loop */
- farLeft = (double)tempRect.left;
-
- /* calculate the width of each band */
- bandWidth = ((double)(tempRect.right-tempRect.left)) / (double)kNumGrayPatterns;
-
- /* Initialize the rectangle that specifies the first band of the blend */
- tempRect.right = tempRect.left + bandWidth;
- distance = bandWidth;
-
- /* There is a pattern resource consisting of 64 shades of gray in MacLib.rsrc
- // that gives a pretty good approximation of a gray ramp from white to black.
- // The following loop performs the actual imaging of the ramp's 64 gray bands.
- */
- for (i=kNumGrayPatterns; i>1; i--) {
- GetIndPattern(&thePat, kGrayPatternRsrc, i);
- FillRect(&tempRect,thePat);
-
- distance += bandWidth;
- tempRect.left = tempRect.right;
- tempRect.right = (short)(farLeft + distance);
- }
-
- tempRect.right = boundRect->right;
- GetIndPattern(&thePat,kGrayPatternRsrc,1);
- FillRect(&tempRect,thePat);
- }
-
-